*&---------------------------------------------------------------------*
*& Report ZS_REPOSRC_DOWNLOAD
*&---------------------------------------------------------------------*
*& Purpose: Download compressed source code from table REPOSRC
*& Author : Daniel Berlin
*&          H. Schwab (loop to output multiple files
*&                     and a few options to select the files)
*& Version: 1.0.2
*& License: CC BY 3.0 (http://creativecommons.org/licenses/by/3.0/)
*&---------------------------------------------------------------------*

* Documentantion of parameters:
* User    ... User who did last change
* AENDAT  ... Date of last change. Idea: use it to export only 'young' files.
* Report  ... Name of report(s) to export. For example export reports where
*             the name start with 'Z'.
* p_test  ... Testflag. X = Testmodus. Show what would be done.
* p_skipsy ... Skip systemuser(s) when exporting reports

REPORT zs_reposrc_download.

DATA: "v_fnam TYPE rlgrap-filename,  " Local file name
      v_file TYPE string,           " Same, but as a string
      v_xstr TYPE xstring,          " Source (compressed)
      v_xlen TYPE i,                " Length of source
      t_xtab TYPE TABLE OF x255.    " Source plugged into a table

DATA reposrc TYPE reposrc.
DATA gv_default_path TYPE string.
DATA: gs_progname(40) TYPE c,
      gt_progname LIKE TABLE OF gs_progname.
DATA: gv_name LIKE reposrc-unam.
DATA: gv_counter TYPE i.

SELECTION-SCREEN BEGIN OF BLOCK eins WITH FRAME .
SELECT-OPTIONS:     user FOR reposrc-unam,           " user who did last change
                    aendat  FOR reposrc-udat.        " date of last change

SELECT-OPTIONS:     report FOR reposrc-progname.     " Filter for report names
PARAMETERS:         p_test TYPE xflag DEFAULT 'X'.   " Testmodus
PARAMETERS:         p_skipsy TYPE xflag DEFAULT 'X'. " Skip system users
SELECTION-SCREEN END OF BLOCK eins.


START-OF-SELECTION.

  " -- Select local file name
  WHILE gv_default_path IS INITIAL AND p_test IS INITIAL.
    gv_default_path = 'H:\tmp'.
    CALL METHOD cl_gui_frontend_services=>directory_browse
      EXPORTING
        window_title    = 'Select Directory'
        initial_folder  = gv_default_path
      CHANGING
        selected_folder = gv_default_path
      EXCEPTIONS
        cntl_error      = 1
        error_no_gui    = 2
        OTHERS          = 3.
    IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*            WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ELSE.
      " In case that user pressed 'cancel' it could be that
      " gv_default_path is empty. In that case we leave progoram.
      IF gv_default_path = ''.
        LEAVE PROGRAM.
      ENDIF.
    ENDIF.

  ENDWHILE.

  " -- Fetch compressed source code
  IF p_skipsy = 'X'.
    " Skip programms of user 'SAP'.
    SELECT progname INTO TABLE gt_progname FROM reposrc
            WHERE progname IN report AND r3state = 'A'
                  AND unam IN user AND udat IN aendat
                  AND unam <> 'SAP'.
  ELSE.
    SELECT progname INTO TABLE gt_progname FROM reposrc
            WHERE progname IN report AND r3state = 'A'
                  AND unam IN user AND udat IN aendat.
  ENDIF.

* Delete files of system users we could not skip up to now.
  IF p_skipsy = 'X'.

    LOOP AT gt_progname INTO gs_progname.
      SELECT SINGLE unam INTO gv_name FROM reposrc
              WHERE progname = gs_progname AND r3state = 'A'
                    AND unam IN user AND udat IN aendat.
      IF ( gv_name = 'SAP' ) OR
         " ( gv_name = 'DDIC' ) OR " There exist programs which were changed from
                                   " normal users but system shows them as DDIC.
                                   " Therefore we do not skip 'DDIC'.
         ( gv_name = 'SAP*' ) .
        DELETE TABLE gt_progname FROM gs_progname.
      ENDIF.
    ENDLOOP.
  ENDIF.

  " Initialisisation of counter
  gv_counter = 0.

  LOOP AT gt_progname INTO gs_progname.
    " Generate Output filename.
    " This is necessary when we would like to check if file exists already
    " and of course it is necessary to later write the file
    " to directory.

    " Replace some special characters in names of reports.
    " On my system report names that contain '/' generate
    " subdirectories. That is not what I want.
    DATA gs_progname_tmp LIKE gs_progname.
    gs_progname_tmp = gs_progname.
    REPLACE ALL OCCURRENCES OF '/' IN gs_progname_tmp WITH '_'.

    CONCATENATE gv_default_path '\' gs_progname_tmp '.raw' INTO v_file.


    " Read report source
    SELECT SINGLE data INTO v_xstr FROM reposrc
            WHERE progname = gs_progname AND r3state = 'A'
                  AND unam IN user AND udat IN aendat.

    v_xlen = xstrlen( v_xstr ).

    " skip empty files
    IF v_xlen = 0.
      CONTINUE.
    ENDIF.

    gv_counter = gv_counter + 1.

    IF p_test = 'X'.
      WRITE: / v_file.
    ELSE.
      " -- Plug source into a table
      CALL METHOD cl_swf_utl_convert_xstring=>xstring_to_table
        EXPORTING
          i_stream = v_xstr
        IMPORTING
          e_table  = t_xtab
        EXCEPTIONS
          OTHERS   = 1.

      " -- Download to local file
      CALL FUNCTION 'GUI_DOWNLOAD'
        EXPORTING
          filetype     = 'BIN'
          filename     = v_file
          bin_filesize = v_xlen
        TABLES
          data_tab     = t_xtab
        EXCEPTIONS
          OTHERS       = 0.
    ENDIF.
  ENDLOOP.

  IF p_test = 'X'.
    WRITE: /, 'Counter: ', gv_counter.
  ENDIF.
